﻿using System;
using System.Text;

namespace Adaptive.Foundation.Tokenizers
{
    /// <summary>
    /// Represents and manages an un-parsed token instance.
    /// </summary>
    /// <remarks>
    /// This is used in basic character and other simple tokenizing operations for the 
    /// purpose of distilling the contents into a parsable object list.
    /// </remarks>
    public class RawToken : AiObjectBase
    {
        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations
        /// <summary>
        /// The actual value being stored.
        /// </summary>
        private string _tokenValue = string.Empty;
        /// <summary>
        /// The index of the instance.
        /// </summary>
        private int _itemIndex = -1;
        /// <summary>
        /// The location in the original string from which the token was parsed.
        /// </summary>
        private int _rawDataLocation = -1;
        /// <summary>
        /// The token type.
        /// </summary>
        private CharacterTokenTypes _tokenType = CharacterTokenTypes.None;
        /// <summary>
        /// The suggested token operation.
        /// </summary>
        private CharacterTokenOperations _operation = CharacterTokenOperations.None;
        /// <summary>
        /// Pointer to the previous token in a list.
        /// </summary>
        private RawToken _previousToken;
        /// <summary>
        /// Pointer to the next token in a list.
        /// </summary>
        private RawToken _nextToken;
        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <remarks>
        /// This is the default constructor.
        /// </remarks>
        public RawToken()
            : base()
        {
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RawToken"/> class.
        /// </summary>
        /// <param name="originalContent">
        /// The content of the token from the original string.
        /// </param>
        public RawToken(string originalContent)
            : base()
        {
            _tokenValue = originalContent;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RawToken"/> class.
        /// </summary>
        /// <param name="originalContent">
        /// The content of the token from the original string.
        /// </param>
        /// <param name="tokenType">
        /// A <see cref="CharacterTokenTypes"/> indicating the type of token being represented.
        /// </param>
        public RawToken(string originalContent, CharacterTokenTypes tokenType)
            : this(originalContent)
        {
            _tokenType = tokenType;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RawToken"/> class.
        /// </summary>
        /// <param name="originalContent">
        /// The content of the token from the original string.
        /// </param>
        /// <param name="tokenType">
        /// A <see cref="CharacterTokenTypes"/> indicating the type of token being represented.
        /// </param>
        /// <param name="operation">
        /// A <see cref="CharacterTokenOperations"/> enumerated value indicating the suggested
        /// parsing operation.
        /// </param>
        public RawToken(string originalContent, CharacterTokenTypes tokenType, CharacterTokenOperations operation)
            : this(originalContent, tokenType)
        {
            _operation = operation;
        }
        /// <summary>
        /// Deallocates internally allocated objects.
        /// </summary>
        /// <param name="disposing">
        /// A value indicating whether the object is being disposed.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            _previousToken = null;
            _nextToken = null;
            _tokenValue = null;
            base.Dispose(disposing);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Properties
         *------------------------------------------------------------------------------*/
        #region Public Properties
        /// <summary>
        /// Gets or sets the actual string value that was parsed into a token.
        /// </summary>
        /// <value>
        /// The originating token value.
        /// </value>
        public string TokenValue
        {
            get
            {
                return _tokenValue;
            }
            set
            {
                _tokenValue = value;
            }
        }
        /// <summary>
        /// Gets or set the index of the instance.
        /// </summary>
        /// <value>
        /// An ordinal index assignment.
        /// </value>
        public int ItemIndex
        {
            get
            {
                return _itemIndex;
            }
            set
            {
                _itemIndex = value;
            }
        }
        /// <summary>
        /// Gets or sets the location in the original string from which the token was parsed.
        /// </summary>
        /// <value>
        /// The ordinal index from which <see cref="TokenValue"/> was read.
        /// </value>
        public int RawDataLocation
        {
            get
            {
                return _rawDataLocation;
            }
            set
            {
                _rawDataLocation = value;
            }
        }
        /// <summary>
        /// Gets or sets the associated token type.
        /// </summary>
        /// <value>
        /// A <see cref="CharacterTokenTypes"/> representing the assigned, 
        /// token type.
        /// </value>
        public CharacterTokenTypes TokenType
        {
            get
            {
                return _tokenType;
            }
            set
            {
                _tokenType = value;
            }
        }
        /// <summary>
        /// Gets or sets the suggested token operation.
        /// </summary>
        /// <value>
        /// A <see cref="CharacterTokenOperations"/> representing the assigned, 
        /// suggested parsing operation.
        /// </value>
        public CharacterTokenOperations Operation
        {
            get
            {
                return _operation;
            }
            set
            {
                _operation = value;
            }
        }
        /// <summary>
        /// Gets or sets the reference/pointer to the previous token in a list.
        /// </summary>
        /// <value>
        /// A <see cref="RawToken"/> instance, or <b>null</b>.
        /// </value>
        public RawToken PreviousToken
        {
            get
            {
                return _previousToken;
            }
            set
            {
                _previousToken = value;
            }
        }
        /// <summary>
        /// Gets or sets the reference/pointer to the next token in a list.
        /// </summary>
        /// <value>
        /// A <see cref="RawToken"/> instance, or <b>null</b>.
        /// </value>
        public RawToken NextToken
        {
            get
            {
                return _nextToken;
            }
            set
            {
                _nextToken = value;
            }
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Removes any object contents and resets the local properties to thier default values.
        /// </summary>
        public override void Clear()
        {
            _tokenValue = string.Empty;
            _itemIndex = -1;
            _nextToken = null;
            _previousToken = null;
            _operation = CharacterTokenOperations.None;
            _rawDataLocation = -1;
            _tokenType = CharacterTokenTypes.None;
            base.Clear();
        }
        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            StringBuilder builder = null;

            builder = new StringBuilder();
            if (_itemIndex > -1)
                builder.Append(_itemIndex.ToString() + ": ");

            if (_tokenType != CharacterTokenTypes.None)
                builder.Append(_tokenType.ToString() + ": ");

            builder.Append(_tokenValue);

            return builder.ToString();
        }
        #endregion
    }
}